package org.cmoine.perspectiveshare.importWizards;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.cmoine.perspectiveshare.model.AlwaysOnActionSetType;
import org.cmoine.perspectiveshare.model.DocumentRoot;
import org.cmoine.perspectiveshare.model.InfoType;
import org.cmoine.perspectiveshare.model.NewWizardActionType;
import org.cmoine.perspectiveshare.model.PageType;
import org.cmoine.perspectiveshare.model.PerspectiveActionType;
import org.cmoine.perspectiveshare.model.ShowViewActionType;
import org.cmoine.perspectiveshare.model.ViewType;
import org.cmoine.perspectiveshare.model.ViewType1;
import org.eclipse.ui.IPageLayout;

public class CodeGenerator {
    private final Map<String, InfoType> infoTypes;
    private final DocumentRoot root;
    private final List<String> visibleViews;

    public CodeGenerator(DocumentRoot root) {
        this.root=root;
        infoTypes=new HashMap<String, InfoType>();
        for (InfoType tmp : root.getPerspective().getLayout().getMainWindow().getInfo()) {
            infoTypes.put(tmp.getPart(), tmp);
        }
        visibleViews=new ArrayList<String>();
        for (ViewType1 viewType : root.getPerspective().getView()) {
            visibleViews.add(viewType.getId());
        }
    }

    public String generate() {
        StringBuffer buf=new StringBuffer("IFolderLayout folder;\n"); //$NON-NLS-1$
        // Add views
        for (InfoType infoType : root.getPerspective().getLayout().getMainWindow().getInfo()) {
            if (!infoType.getPart().equals(IPageLayout.ID_EDITOR_AREA)) {
                if (hasVisibleView(infoType.getPart())) {
                    InfoType relativeInfoType=infoType;
                    while (relativeInfoType != null && !hasVisibleView(relativeInfoType.getRelative())) {
                        relativeInfoType=infoTypes.get(relativeInfoType.getRelative());
                    }
                    String relative;
                    if (relativeInfoType == null)
                        relative="layout.getEditorArea()"; //$NON-NLS-1$
                    else
                        relative='"' + relativeInfoType.getRelative() + '"';

                    int relationship=infoType.getRelationship();
                    float ratio=infoType.getRatio();
                    if (relativeInfoType == null || relativeInfoType.getPart().equals(IPageLayout.ID_EDITOR_AREA)) {
                        relationship=invert(relationship);
                    }

                    buf.append(format("folder=layout.createFolder(\"{0}\", {1}, {2}f, {3});\n", infoType.getPart(), relationship, ratio, relative)); //$NON-NLS-1$
                    for (PageType pageType : infoType.getFolder().getPage()) {
                        if (visibleViews.contains(pageType.getContent()))
                            buf.append(format("folder.addView(\"{0}\");\n", pageType.getContent())); //$NON-NLS-1$
                    }
                }
            }
        }
        // Add fast views
        for (ViewType fastView : root.getPerspective().getFastViews().getView()) {
            buf.append(format("layout.addFastView(\"{0}\", {1}f);\n", fastView.getId(), fastView.getRatio())); //$NON-NLS-1$
        }
        // Actions sets
        for (AlwaysOnActionSetType actionSetType : root.getPerspective().getAlwaysOnActionSet()) {
            buf.append(format("layout.addActionSet(\"{0}\");\n", actionSetType.getId())); //$NON-NLS-1$
        }
        // New wizards
        for (NewWizardActionType newWizardType : root.getPerspective().getNewWizardAction()) {
            buf.append(format("layout.addNewWizardShortcut(\"{0}\");\n", newWizardType.getId())); //$NON-NLS-1$
        }
        // View shortcuts
        for (ShowViewActionType showViewType : root.getPerspective().getShowViewAction()) {
            buf.append(format("layout.addShowViewShortcut(\"{0}\");\n", showViewType.getId())); //$NON-NLS-1$
        }
        // Perspectives shortcuts
        for (PerspectiveActionType perspectiveType : root.getPerspective().getPerspectiveAction()) {
            buf.append(format("layout.addPerspectiveShortcut(\"{0}\");\n", perspectiveType.getId())); //$NON-NLS-1$
        }

        return buf.toString();
    }

    private String format(String pattern, Object... params) {
        return new MessageFormat(pattern, Locale.ENGLISH).format(params, new StringBuffer(), null).toString();
    }

    private int invert(int relationship) {
        switch (relationship) {
            case IPageLayout.LEFT:
                return IPageLayout.RIGHT;
            case IPageLayout.RIGHT:
                return IPageLayout.LEFT;
            case IPageLayout.TOP:
                return IPageLayout.BOTTOM;
            case IPageLayout.BOTTOM:
                return IPageLayout.TOP;
        }
        return 0;
    }

    private boolean hasVisibleView(String part) {
        if (infoTypes.containsKey(part)) {
            for (PageType pageType : infoTypes.get(part).getFolder().getPage()) {
                if (visibleViews.contains(pageType.getContent()))
                    return true;
            }
        }
        return false;
    }
}
